home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Misc Servers / Zope.exe / EXPORTIMPORTXML.PY < prev    next >
Encoding:
Python Source  |  2000-07-12  |  9.0 KB  |  319 lines

  1. import string, struct, sys, tempfile
  2. import Shared.DC.xml.ppml
  3. import Shared.DC.xml.xyap
  4.  
  5. ppml=Shared.DC.xml.ppml
  6. xyap=Shared.DC.xml.xyap
  7. xyap=xyap.xyap
  8. p64=ppml.p64
  9. u64=ppml.u64
  10. cp=ppml.cp
  11.  
  12. try: from cStringIO import StringIO
  13. except: from StringIO import StringIO
  14.  
  15. export_end_marker='\377'*16
  16. StringType=type('')
  17.  
  18. class ZopeData:
  19.     def __init__(self, parser, tag, attrs):
  20.         self._pos=0
  21.         self.file=parser.file
  22.         self.tempfile=parser.tempfile
  23.  
  24.     def append(self, transaction, f=None):
  25.         file=self.file
  26.         write=file.write
  27.         tfile=self.tempfile
  28.         dlen=tfile.tell()
  29.         tfile.seek(0)
  30.         id=transaction.serial
  31.         user, desc, ext = transaction._ude
  32.         transaction._ude=None
  33.  
  34.         tlen=transaction._thl
  35.         pos=self._pos
  36.         file.seek(pos)
  37.         tl=tlen+dlen
  38.         stl=p64(tl)
  39.         write(struct.pack(
  40.             ">8s" "8s" "c"  "H"         "H"         "H"
  41.             , id, stl, ' ', len(user), len(desc), len(ext),
  42.             ))
  43.         if user: write(user)
  44.         if desc: write(desc)
  45.         if ext: write(ext)
  46.  
  47.         cp(tfile,file,dlen)
  48.  
  49.         write(stl)
  50.         self._pos=pos+tl+8
  51.  
  52.  
  53. class Transaction:
  54.     def __init__(self, parser, tag, attrs):
  55.         self.file=parser.file
  56.         self.tempfile=parser.tempfile
  57.  
  58.         self.tempfile.seek(0)
  59.        
  60.         tyme=attrs['time']
  61.         start=0
  62.         stop=string.find(tyme[start:],'-')+start
  63.         year=string.atoi(tyme[start:stop])
  64.         start=stop+1
  65.         stop=string.find(tyme[start:],'-')+start
  66.         month=string.atoi(tyme[start:stop])
  67.         start=stop+1
  68.         stop=string.find(tyme[start:],' ')+start
  69.         day=string.atoi(tyme[start:stop])
  70.         start=stop+1
  71.         stop=string.find(tyme[start:],':')+start
  72.         hour=string.atoi(tyme[start:stop])
  73.         start=stop+1
  74.         stop=string.find(tyme[start:],':')+start
  75.         minute=string.atoi(tyme[start:stop])
  76.         start=stop+1
  77.         second=string.atof(tyme[start:])
  78.         t=(((((year-1900)*12+month-1)*31+day-1)*24+hour)*60+minute)
  79.         t=struct.pack(">If",t,second*(1L<<32)/60)
  80.         self.serial=t
  81.         self._user=user=''
  82.         self._descr=desc=''
  83.         self._ext=ext=''
  84.         self._thl= 23+len(user)+len(desc)+len(ext)
  85.         self._ude= user, desc, ext
  86.         self._index={}
  87.         self._tindex=[]
  88.         self._pos=0
  89.         self._oid='\0\0\0\0\0\0\0\0'
  90.  
  91.     def append(self, data):
  92.         version=''
  93.         old=self._index.get(self._oid,0)
  94.         pnv=None
  95.         if old:
  96.             file=self.file
  97.             file.seek(old)
  98.             read=file.read
  99.             h=read(42)
  100.             doid,oserial,sprev,stloc,vlen,splen = unpack(">8s8s8s8sH8s", h)
  101.             if doid != self.serial: raise CorruptedDataError, h
  102.             
  103.         tfile=self.tempfile
  104.         write=tfile.write
  105.         pos=self._pos
  106.         serial=self.serial
  107.         oid=self._oid
  108.         here=tfile.tell()+pos+self._thl
  109.         self._tindex.append((self._oid, here))
  110.         serial=self.serial
  111.         write(struct.pack(">8s8s8s8sH8s", oid, serial, p64(old), p64(pos),
  112.                    len(version), p64(len(data))))
  113.  
  114.         for x in data[2:]:
  115.             write(x)
  116.  
  117.         return serial
  118.  
  119. def save_user(self, tag, data):
  120.     transaction=self._transaction
  121.     if len(data)>2: v=data[2]
  122.     else: v=''
  123.     self._user=v
  124.     transaction._thl=self._transaction._thl+len(v)
  125.     transaction._ude=v,transaction._ude[1],transaction._ude[2]
  126.     return v
  127.  
  128. def save_description(self, tag, data):
  129.     transaction=self._transaction
  130.     if len(data)>2: v=data[2]
  131.     else: v=''
  132.     a=data[1]
  133.     if a.has_key('encoding'): encoding=a['encoding']
  134.     else: encoding=''
  135.     if encoding:
  136.         v=unconvert(encoding,v)
  137.     transaction._descr=v
  138.     transaction._thl=transaction._thl+len(v)
  139.     transaction._ude=transaction._ude[0],v,transaction._ude[2]
  140.     return v
  141.  
  142. def save_rec(self, tag, data):
  143.     a=data[1]
  144.     if a.has_key('id'):
  145.         a['id']=p64(string.atoi(a['id'])+1)
  146.     if a.has_key('time'):
  147.         start=0
  148.         stop=string.find(a['time'][start:],'-')+start
  149.         year=string.atoi(a['time'][start:stop])
  150.         start=stop+1
  151.         stop=string.find(a['time'][start:],'-')+start
  152.         month=string.atoi(a['time'][start:stop])
  153.         start=stop+1
  154.         stop=string.find(a['time'][start:],' ')+start
  155.         day=string.atoi(a['time'][start:stop])
  156.         start=stop+1
  157.         stop=string.find(a['time'][start:],':')+start
  158.         hour=string.atoi(a['time'][start:stop])
  159.         start=stop+1
  160.         stop=string.find(a['time'][start:],':')+start
  161.         minute=string.atoi(a['time'][start:stop])
  162.         start=stop+1
  163.         second=string.atof(a['time'][start:])
  164.         a['time']=struct.pack(">If",(((((year-1900)*12)+month-1)*31+day-1)*24+
  165.                                    hour)*60 +minute, second*(1L<<32)/60)
  166.         data[1]=a
  167.         
  168.     return data
  169.  
  170. def start_transaction(self, tag, attrs):
  171.     self._transaction=Transaction(self, tag, attrs)
  172.     return self._transaction
  173.  
  174. def start_ZopeData(self, tag, attrs):
  175.     self._ZopeData=ZopeData(self, tag, attrs)
  176.     return self._ZopeData
  177.  
  178. def XMLtobbb(infile, outfile, binary=0):
  179.     import Shared.DC.xml.pyexpat
  180.     if type(infile) is StringType:
  181.         data=open(infile).read()
  182.     if type(outfile) is StringType:
  183.         outfile=open(outfile,'w'+'b')
  184.     F=ppml.xmlPickler()
  185.     F.end_handlers['user'] = save_user
  186.     F.end_handlers['description'] = save_description
  187.     F.end_handlers['rec'] = save_rec
  188.     F.start_handlers['transaction'] = start_transaction
  189.     F.start_handlers['ZopeData'] = start_ZopeData
  190.     F.binary=binary
  191.     F.file=outfile
  192.     F.tempfile=tempfile.TemporaryFile()
  193.     p=xml.parsers.pyexpat.ParserCreate()
  194.     p.CharacterDataHandler=F.handle_data
  195.     p.StartElementHandler=F.unknown_starttag
  196.     p.EndElementHandler=F.unknown_endtag
  197.     r=p.Parse(data)
  198.     return r
  199.  
  200. def save_record(self, tag, data):
  201.     file=self.file
  202.     write=file.write
  203.     pos=file.tell()
  204.     file.seek(pos)
  205.     a=data[1]
  206.     if a.has_key('id'): oid=a['id']
  207.     oid=ppml.p64(string.atoi(oid))
  208.     v=''
  209.     for x in data[2:]:
  210.         v=v+x
  211.     l=ppml.p64(len(v))
  212.     v=oid+l+v
  213.     return v
  214.  
  215. class zopedata:
  216.     def __init__(self, parser, tag, attrs):
  217.         self.file=parser.file
  218.         write=self.file.write
  219.         write('ZEXP')
  220.  
  221.     def append(self, data):
  222.         file=self.file
  223.         write=file.write
  224.         pos=file.tell()
  225.         file.seek(pos)
  226.         write(data)
  227.  
  228. def start_zopedata(self, tag, data):
  229.     return zopedata(self, tag, data)
  230.  
  231. def save_zopedata(self, tag, data):
  232.     file=self.file
  233.     write=file.write
  234.     pos=file.tell()
  235.     file.seek(pos)
  236.     write(export_end_marker)
  237.     
  238.  
  239. def XMLtoExport(infile, outfile):
  240.     import Shared.DC.xml.pyexpat.pyexpat
  241.     pyexpat=Shared.DC.xml.pyexpat.pyexpat
  242.     if type(infile) is StringType:
  243.         infile=open(infile)
  244.     if type(outfile) is StringType:
  245.         outfile=open(outfile,'w'+'b')
  246.     data=infile.read()
  247.     F=ppml.xmlPickler()
  248.     F.end_handlers['record'] = save_record
  249.     F.end_handlers['ZopeData'] = save_zopedata
  250.     F.start_handlers['ZopeData'] = start_zopedata
  251.     F.binary=1
  252.     F.file=outfile
  253.     p=pyexpat.ParserCreate()
  254.     p.CharacterDataHandler=F.handle_data
  255.     p.StartElementHandler=F.unknown_starttag
  256.     p.EndElementHandler=F.unknown_endtag
  257.     r=p.Parse(data)
  258.     return r
  259.  
  260. def XMLrecord(oid,len,p):
  261.     q=ppml.ToXMLUnpickler
  262.     f=StringIO(p)
  263.     u=q(f)
  264.     u.idprefix=str(oid)+'.'
  265.     p=u.load().__str__(4)
  266.     if f.tell() < len:
  267.         p=p+u.load().__str__(4)
  268.     String='  <record id="%s">\n%s  </record>\n' % (oid, p)
  269.     return String
  270.  
  271.  
  272. def ExporttoXML(file):
  273.     String=''
  274.     if type(file) is StringType:
  275.         file=open(file,'rb')
  276.     read=file.read
  277.     if read(4) !='ZEXP':
  278.         raise POSException.ExportError, 'Invalid export header'
  279.  
  280.     String=String+'<?xml version="1.0"?>\012<ZopeData>\n'
  281.     while 1:
  282.         h=read(16)
  283.         if h == export_end_marker: break
  284.         if len(h) != 16: raise ExportError, 'Truncated export file'
  285.         oid=ppml.u64(h[:8])
  286.         l=ppml.u64(h[8:16])
  287.         pos=file.tell()
  288.         p=read(l)
  289.         if len(p) != l: raise ExportError, 'Truncated export file'
  290.         String=String+XMLrecord(oid,l,p)
  291.         l=l+pos
  292.         
  293.     String=String+'</ZopeData>\n'
  294.     return String
  295.  
  296.  
  297. # End exportToXML    
  298.  
  299. def XMLstringToExport(data, outfile):
  300.     import Shared.DC.xml.pyexpat
  301.     if type(outfile) is StringType:
  302.         outfile=open(outfile,'w'+'b')
  303.     F=ppml.xmlPickler()
  304.     F.end_handlers['record'] = save_record
  305.     F.end_handlers['ZopeData'] = save_zopedata
  306.     F.start_handlers['ZopeData'] = start_zopedata
  307.     F.binary=1
  308.     F.file=outfile
  309.     p=xml.parsers.pyexpat.ParserCreate()
  310.     p.CharacterDataHandler=F.handle_data
  311.     p.StartElementHandler=F.unknown_starttag
  312.     p.EndElementHandler=F.unknown_endtag
  313.     r=p.Parse(data)
  314.     return r
  315.     
  316.  
  317. if __name__=='__main__': exportToXML(sys.argv[1])
  318.  
  319.